import tools from "../../../tools"
import hierParentModel from './hierParentModel'
import modelObject from 'public/model/starModel'
import lodash from 'lodash'

const idName = 'nodeId'
export default class simpleMapModel extends hierParentModel {
  constructor(hierProperties, web) {
    super(hierProperties, simpleMapModel)
    this.web = web || {}
    this.sourceData = {}
    this.rootId = ''
    // this.addRoot()
  }
  set(hierProperties, web) {
    this.hierProperties = hierProperties
    this.web = web || {}
    this.addRoot()
    this.loadSourceData()
  }
  async loadSourceData() {
    this.sourceData = await this.getSourceData()
  }
  // 读取source的数据
  async getSourceData() {
    let objMap = {}
    let api = []

    if (!this.web.source || !this.web.source.length) {
      return {}
    }

    this.web.source.forEach(item => {
      if (item.name && item.model) {
        let obj = modelObject.create(item.model[0] + 'Collection')
        api.push(
          obj.query(obj.util.getFilter( {type: item.model[1], className: item.model[2]} )),
        )
        objMap[item.name] = obj
      }
    })
    let res = await Promise.all(api)
    Object.keys(objMap).forEach(key => {
      let record = objMap[key].record || objMap[key].records
      if (record.length) {
        objMap[key] = record[0].values || record[0] || {}
      } else if (typeof record === 'object') {
        objMap[key] = record.values || record || {}
      } else {
        objMap[key] = {}
      }
    })
    return objMap
  }
  // 递归计算所有节点的公式
  async calcAllExp(parentItem) {
    let tmpVarObj = await this.getSourceData()
    let calcRes = this.calcChildExp(parentItem, tmpVarObj)
    console.log("file: simpleMapModel.js:45 calcAllExp", calcRes, tmpVarObj, this.hierProperties)
    return calcRes
  }
  // 计算所有子节点的公式
  calcChildExp(parentItem, tmpVarObj, errContent=[]) {
    let parentIndex = this.findIndex(idName, parentItem[idName])
    let child = this.findNext(parentItem[idName])
    let childSumValue = 0

    // 计算子元素value，并汇总
    child.forEach((item) => {
      let {flag, res, sumValue} = this.calcChildExp(item, tmpVarObj, errContent)

      res = flag ? res : 0
      tmpVarObj[item.varName] = res
      childSumValue += res
    })
    // 计算当前元素value
    tmpVarObj.sumValue = childSumValue
    let calcRes = this.calcExp(tmpVarObj, parentItem.expression)
    let value = calcRes.flag ? calcRes.res : 0
    !calcRes.flag && errContent.push(`${parentItem.name}: ${calcRes.res}`)

    value = lodash.isNumber(value) ? lodash.round(value,2) : value
    this.hierProperties.content[parentIndex].value = value

    // 向上一级汇总value
    return {
      flag: calcRes.flag,
      res: value,
      sumValue: lodash.isNumber(childSumValue) ? lodash.round(childSumValue + value, 2) : 0,
      errContent
    }
  }
  // 验证表达式
  calcExp($={}, content="") {
    try {
      if (!content) {
        return {flag: true, res: 0}
      }
      
      let varList = Object.keys($).filter(item => !!item)
      let reg = new RegExp('(^|\\s|\\+|-|\\*|\\/)(' + varList.join('|') +')', 'g')

      content = content.replace(reg, '$1$.$2')
      function sum() {return $.sumValue || 0}

      // content = content.replace(/(<#)+/g, '').replace(/(#>)+/g, '')
      console.log("file: simpleMapModel calcExp1", $, content)
      // const fn = new Function('$', 'return ' + content);
  
      let res = eval(content) || 0  //  eval(content)  fn($)
      return {flag: true, res}
    }
    catch(err) {
      console.log("🚀 ~ file: common.js:120 ~ calcExp ~ err:", err)
      return {flag: false, res: err}
    }
  }
  formatContent() {
  }
  addRoot() {
    if (!this.hierProperties.content) {
      this.hierProperties = simpleMapModel.tpl()
    }
    let rootData = this.find('name', 'root')
    if (!rootData) {
      let rootId = '_root'
      let firstWCId = tools.uuid()
      let newRoot = simpleMapModel.rootItemTpl({id: rootId})
      let newItem = simpleMapModel.itemTpl({id: firstWCId, prev: [rootId]})

      this.web = {
        source: [],
        data: [
          this.webRootTpl({id: rootId}),
          {
            ...this.webWCTpl({
              id: firstWCId,
              parentId: rootId,
            }),
            fixed: false,
            width: 90,
            height: 90,
            "x": 200,
            "y": 20,
          },
          this.webLineTpl({
            to: firstWCId
          }),
        ]
      }
      this.rootId = rootId
      this.hierProperties.content = [
        newRoot,
        newItem,
      ]
    } else {
      this.rootId = rootData[idName]
    }
  }
  // #region tpl
  itemTpl(item={}) {
    return simpleMapModel.itemTpl(item)
  }
  static tpl() {
    return {
      type: 'chain',
      content: [
        // item
      ]
    }
  }
  static rootItemTpl({id}) {
    id = id || tools.uuid();
    return {
      [idName]: id,
      prev: [], //前驱节点
      nodeType: "root",
      name: "root",
      // varName: 'root',
      expression: '',
      value: null,
      // properties: [{type:'String'}],
      link: {},
    }
  }
  static itemTpl(item={}) {
    let {id, prev} = item
    id = id || tools.uuid();
    return {
      [idName]: id,
      prev: prev || [], //前驱节点
      nodeType: "leaf",
      name: '',
      varName: '',
      expression: '',
      value: null,
      // properties: [{type:'String'}],
      link: {},
    }
  }
  // web相关
  webRootTpl({id}) {
    id = id || tools.uuid()
    return {
        id,
        name: "root",
        type: "routingRoot",
        shapeType: "routingRoot",
        properties: {
            id,
            name: 'root',
            link: {},
            // varName: 'root'
        },
        fixed: false,
        width: 90,
        height: 90,
        x: 10,
        y: 20,
    }
  }
  webWCTpl(item={}){
    let id = item.id || tools.uuid();
    return {
        parentId: item.parentId,
        id,
        type: "workCenter",
        shapeType: "workCenter",
        prev: [],
        properties: {
            id,
            name: 'new node',
            link: item.link || {}
        },
    }
  }
  webLineTpl(item={}){
    return {
        id: tools.uuid(),
        from: item.from || "_root",
        to: item.to || "_0",
        "type": "line",
        "points": [
          {
            "x": 100,
            "y": 65
          },
          {
            "x": 200,
            "y": 65
          }
        ],
        "width": 100,
        "height": 0,
        "x": 100,
        "y": 65,
        "stroke": "#2196F3",
        "connectType": "elbow",
        "strokeWidth": 2,
        "cornersRadius": 0,
        "fromSide": "right",
        "toSide": "left",
        "forwardArrow": "filled",
        "backArrow": "",
        "added": true
    }
  }
  //#endregion
}